﻿using System.Collections.Generic; 
using UnityEditor; 
using UnityEditor.IMGUI.Controls;
using UnityEngine; 

namespace XFGameFramework.EquipmentSystem
{
    public class ConfigsWindow : SplitWindow
    {

        [MenuItem("Window/XFKT/XFGameFramework/InstalledExtension/EquipmentSystem", false, 10)]
        static void Open()
        {
            GetWindow<ConfigsWindow>().Show();
        }

        #region 字段

        private const string SELECT_GUID_KEY = "XFGameFramework.EquipmentSystem.SELECT_GUID_KEY";
            
        private GUIContent currentEquipmentConfigContent;

        private string searchStr;

        [SerializeField]
        private TreeViewStateGroup treeViewStateGroup = new TreeViewStateGroup();

#if UNITY_6000_2_OR_NEWER
        private TreeViewState<int> equipmentListState => treeViewStateGroup.Get(currentEquipmentConfig.GetHashCode());
#else
        private TreeViewState equipmentListState => treeViewStateGroup.Get(currentEquipmentConfig.GetHashCode());
#endif


        internal EquipmentListTree equipmentListTree;
          
        internal EquipmentsConfig currentEquipmentConfig; 

        private float timer = 0;

        internal int currentShowEquipmentId = 0;

        internal static int DefaultSelectSkillId = -1;

        private float lastRepaintCount = 0;

        private int currentID;
        public int idChangeCount;

#endregion


        #region 属性

        internal static string SelectGUID
        {
            get
            {
                return EditorPrefs.GetString(SELECT_GUID_KEY);
            }
            set
            {
                EditorPrefs.SetString(SELECT_GUID_KEY, value);
            }

        }

        #endregion


        #region 生命周期

        private void Awake()
        {
            titleContent = new GUIContent("装备配置窗口", "装备配置窗口"); 
        }
         

        private void Update()
        {
            lastRepaintCount++;
            if (lastRepaintCount > 15) { 
                Repaint();
                lastRepaintCount = 0;
            }
        }

        protected override void OnGUI()
        { 

            if ( Time.realtimeSinceStartup - timer > 1 && currentEquipmentConfig == null)
            {
                currentEquipmentConfig = GetCurrentConfig();
                timer = Time.realtimeSinceStartup;
            }

            if (currentEquipmentConfig == null)
            {
                EmptyGUI();
            }
            else
            {
                base.OnGUI();
            }
        }


        #endregion


        #region 方法

        internal EquipmentsConfig GetCurrentConfig()
        {
            if (!string.IsNullOrEmpty(SelectGUID))
            {
                string assets_path = AssetDatabase.GUIDToAssetPath(SelectGUID);
                EquipmentsConfig config = AssetDatabase.LoadAssetAtPath<EquipmentsConfig>(assets_path);

                if (config != null)
                    return config;
            }

            List<EquipmentsConfig> allConfig = EquipmentsConfigController.GetAllEquipmentsConfig();

            if (allConfig == null || allConfig.Count == 0)
                return null;

            SelectGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(allConfig[0]));
            return allConfig[0]; 
        }
          
        private void EmptyGUI()
        {

            GUILayout.BeginHorizontal();

            GUILayout.FlexibleSpace();

            GUILayout.BeginVertical();
            GUILayout.FlexibleSpace();
            GUILayout.Label("未查询到装备配置文件!");
            if (GUILayout.Button("立即创建"))
            {
                CreateNew();
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

        }

        protected override void DrawGUILeft(Rect rect)
        {
            base.DrawGUILeft(rect);
            GUILayout.BeginArea(rect);
            DrawLeft(rect);
            GUILayout.EndArea();
        }

        protected override void DrawGUIRight(Rect rect)
        {
            base.DrawGUIRight(rect);
            GUILayout.BeginArea(rect);
            DrawRight();
            GUILayout.EndArea();
        }

        private void DrawLeft(Rect left)
        {
            if (currentEquipmentConfigContent == null)
                currentEquipmentConfigContent = new GUIContent();

            if (currentEquipmentConfig == null)
                return;
            
            currentEquipmentConfigContent.text = GetEquipmentConfigName(currentEquipmentConfig);

            currentEquipmentConfigContent.tooltip = AssetDatabase.GetAssetPath(currentEquipmentConfig);

            GUILayout.BeginHorizontal();

            EditorGUI.BeginChangeCheck();

            searchStr = EditorGUILayout.TextField(string.Empty,searchStr, "SearchTextField",GUILayout.MinWidth(0));

            if (EditorGUI.EndChangeCheck())
            {
                if (string.IsNullOrEmpty(searchStr) && equipmentListTree.state.selectedIDs.Count > 0)
                {
                    EditorApplication.delayCall += () =>
                    {
                        equipmentListTree.FrameItem(equipmentListTree.state.selectedIDs[0]);
                    };
                }
            }

            if (EditorGUILayout.DropdownButton(currentEquipmentConfigContent, FocusType.Passive, EditorStyles.toolbarDropDown, GUILayout.Width(this.position.width * 0.35f * 0.3f)))
            {
                GenericMenu menu = new GenericMenu();
                 
                foreach (var item in EquipmentsConfigController.GetAllEquipmentsConfig())
                {
                    string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(item));
                    bool isOn = SelectGUID == guid;
 
                    menu.AddItem(new GUIContent(GetEquipmentConfigName(item)), isOn, () =>
                    {

                        SelectGUID = guid; 
                        EditorGUIUtility.PingObject(item);
                       
                        if (!isOn)
                        {
                            SetCurrentConfigs(item);
                        }
                    });
                }

                menu.AddSeparator(string.Empty);

                menu.AddItem(new GUIContent("新建装备配表"), false, () =>
                {
                    CreateNew();
                });

                menu.ShowAsContext();
            }

            GUILayout.EndHorizontal();
              
            if (equipmentListTree == null)
            {
                equipmentListTree = new EquipmentListTree(equipmentListState, currentEquipmentConfig);
                equipmentListTree.Reload(); 
            }

            equipmentListTree.searchString = searchStr;

            left.Set(left.x, left.y + 20, left.width , left.height - 20);
            equipmentListTree.OnGUI(left);


            if (equipmentListTree != null && equipmentListTree.EquipmentsConfig != currentEquipmentConfig)
                equipmentListTree = null;

        }

        private string GetEquipmentConfigName(EquipmentsConfig config) 
        {
            if (string.IsNullOrEmpty(config.displayName))
                return config.name;
             
            return string.Format("{0}({1})",config.name,config.displayName);
        }

        private void DrawRight()
        {
            // 判断是否为空 TODO 

            if (IsEmpty()) 
            {
                GUILayout.FlexibleSpace();
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                GUILayout.Label("空!");
                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();
                GUILayout.FlexibleSpace();
                return;
            }


            if (equipmentListState.selectedIDs.Count == 1)
            {
                DrawData(); 
            }
            else if (equipmentListState.selectedIDs.Count == 0)
            {
                GUILayout.FlexibleSpace();
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                GUILayout.Label("空!");
                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();
                GUILayout.FlexibleSpace();
            }
            else
            {
                GUILayout.FlexibleSpace();
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                Color origin = GUI.color;
                GUI.color = Color.yellow;
                GUILayout.Label("不支持同时编辑多个配置!");
                GUI.color = origin;
                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();
                GUILayout.FlexibleSpace();
            }  
        }

        private void DrawData()
        {
            int id = equipmentListState.selectedIDs[0];

            if (currentID != id)
            {
                idChangeCount++;
                if (idChangeCount > 2)
                {
                    // 如果当前帧是Layout ，不能设置，因为当前帧会被return 
                    // 如果当前帧被return , 下一帧repaint 会报错，因为没有位置数据
                    if (Event.current.type != EventType.Layout) 
                    {  
                        currentID = id;
                        idChangeCount = 0;
                    } 
                }
                // 这样处理的目的是 为了防止 EditorGUILayout.DelayedIntField 在编辑时 ,
                // 直接切换id,  EditorGUILayout.DelayedIntField  返回的值会直接给新选中的数据， 导致数据错误的情况
                return;
            }


            EquipmentConfigData data = currentEquipmentConfig.GetEquipmentConfigData(id);
            EquipmentConfigDataInspector.Instance.OnInspectorGUI(this, currentEquipmentConfig, data);
        }

        internal bool IsEmpty()
        {
            if (currentEquipmentConfig == null)
                return true;
             
            for (int i = 0; i < currentEquipmentConfig.Equipments.Count; i++)
            { 
                if (currentEquipmentConfig.Equipments[i] != null)
                    return false;
            }


            return true;
        }


        public void SetSelection(int id) 
        {
            if (equipmentListTree != null)
            {
                equipmentListTree.SetSelection(new int[] { id });
            }
            else 
            {
                EditorApplication.delayCall += () => 
                { 
                    if(equipmentListTree != null)
                        equipmentListTree.SetSelection(new int[] { id });
                };
            }

        }

        public void SetCurrentConfigs(EquipmentsConfig equipmentsConfig) {
            currentID = -1;
            currentEquipmentConfig = equipmentsConfig;

            SelectGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath(equipmentsConfig));

            if (equipmentListTree != null)
            {
                equipmentListTree.Reload();
            }
        }

        #endregion

         
        #region 创建

        private void CreateNew()
        {
            string path = EditorUtility.OpenFolderPanel("请选择文件夹", Application.dataPath, string.Empty);

            if (string.IsNullOrEmpty(path)) return;

            if (path.StartsWith(Application.dataPath))
            {
                path = path.Replace(Application.dataPath, string.Empty);
                path = string.Format("Assets{0}", path);
    
                EquipmentsConfig skillsConfig = CreateInstance<EquipmentsConfig>();
                skillsConfig.start_id = InitIDStart(); 

                EquipmentsConfigController.CreateAsset(skillsConfig, path);

                SelectGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skillsConfig));
                EditorGUIUtility.PingObject(skillsConfig);

                if (equipmentListTree != null)
                    equipmentListTree.Reload();
            }
            else
            {
                this.ShowNotification(new GUIContent("请把资源保存到Assets目录下!"));
            }
        }
  
        private int InitIDStart()
        {
            int max_id_start = 0;

            foreach (var item in EquipmentsConfigController.GetAllEquipmentsConfig())
            {
                if (item.start_id > max_id_start)
                    max_id_start = item.start_id;
            }

            return max_id_start + 1000;
        }

        #endregion

         
    }

}

